<?php

declare(strict_types=1);

namespace SixShop\Wangdian;

use Psr\Http\Client\ClientInterface;
use Psr\Log\LoggerInterface;
use SixShop\Wangdian\Auth\Authenticator;
use SixShop\Wangdian\Config\Config;
use SixShop\Wangdian\Http\HttpClient;
use SixShop\Wangdian\Response\ApiResponse;
use SixShop\Wangdian\Response\ResponseHandler;
use SixShop\Wangdian\Services\BasicService;
use SixShop\Wangdian\Services\GoodsService;
use SixShop\Wangdian\Services\PurchaseService;
use SixShop\Wangdian\Services\RefundService;
use SixShop\Wangdian\Services\StockService;
use SixShop\Wangdian\Services\TradeService;

/**
 * Main SDK client for Wangdian API
 */
class Client
{
    private readonly HttpClient $httpClient;
    private readonly Authenticator $authenticator;
    private readonly ResponseHandler $responseHandler;

    // Service instances
    private ?BasicService $basicService = null;
    private ?GoodsService $goodsService = null;
    private ?PurchaseService $purchaseService = null;
    private ?RefundService $refundService = null;
    private ?StockService $stockService = null;
    private ?TradeService $tradeService = null;

    public function __construct(
        private readonly Config $config,
        ?ClientInterface $httpClient = null,
        ?LoggerInterface $logger = null
    ) {
        $this->httpClient = new HttpClient($this->config, $httpClient, $logger);
        $this->authenticator = new Authenticator($this->config);
        $this->responseHandler = new ResponseHandler();
    }

    /**
     * Make a raw API call
     */
    public function call(string $endpoint, array $params = []): ApiResponse
    {
        // Add authentication parameters and signature
        $authenticatedParams = $this->authenticator->addAuthParams($params);

        // Make HTTP request
        $responseData = $this->httpClient->post($endpoint, $authenticatedParams);

        // Handle and validate response
        $response = $this->responseHandler->handle($responseData);
        
        // Throw exception if response indicates error
        $this->responseHandler->validateOrThrow($responseData);

        return $response;
    }

    /**
     * Get Basic service (shops, warehouses, logistics, etc.)
     */
    public function basic(): BasicService
    {
        return $this->basicService ??= new BasicService($this);
    }

    /**
     * Get Goods service (products, specifications, etc.)
     */
    public function goods(): GoodsService
    {
        return $this->goodsService ??= new GoodsService($this);
    }

    /**
     * Get Purchase service (purchase orders, returns, etc.)
     */
    public function purchase(): PurchaseService
    {
        return $this->purchaseService ??= new PurchaseService($this);
    }

    /**
     * Get Refund service (refund processing, etc.)
     */
    public function refund(): RefundService
    {
        return $this->refundService ??= new RefundService($this);
    }

    /**
     * Get Stock service (inventory management, transfers, etc.)
     */
    public function stock(): StockService
    {
        return $this->stockService ??= new StockService($this);
    }

    /**
     * Get Trade service (orders, logistics sync, etc.)
     */
    public function trade(): TradeService
    {
        return $this->tradeService ??= new TradeService($this);
    }

    /**
     * Get the configuration
     */
    public function getConfig(): Config
    {
        return $this->config;
    }

    /**
     * Get the HTTP client
     */
    public function getHttpClient(): HttpClient
    {
        return $this->httpClient;
    }

    /**
     * Get the authenticator
     */
    public function getAuthenticator(): Authenticator
    {
        return $this->authenticator;
    }

    /**
     * Get the response handler
     */
    public function getResponseHandler(): ResponseHandler
    {
        return $this->responseHandler;
    }
}